﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows.Data;
using System.Collections.ObjectModel;
using System.Windows.Media;
using System.Windows.Input;
using System.Windows.Controls.Primitives;
namespace WpfApplication1
{

    /// <summary>
    /// Interaction logic for T1.xaml
    /// </summary>
    public partial class T1 : UserControl
    {
        public string SearchText
        {
            get
            {
                return null;
            }
            set
            {
                if (value.Trim().Equals(String.Empty))
                {
                    text1.Background = null;
                    return;
                }
                var t = GetTreeViewItem(tree1, value);
                if (t != null)
                {
                    t.IsSelected = true;
                    t.BringIntoView();
                    text1.Background = null;
                }
                else
                {
                    text1.Background = FindResource("NotFound") as Brush;
                }
                try
                {
	                grid1.SelectedValue = null;
	                var item = grid1.Items.Cast<AcItem>().FirstOrDefault(o => o.Name.StartsWith(value));
	                if (item !=null)
	                    grid1.SelectedValue = item;
                }
                catch (System.Exception ex)
                {
                	
                }
            }
        }
        private ObservableCollection<AcItem> _list = new ObservableCollection<AcItem>();

        public ObservableCollection<AcItem> Items
        {
            get
            {
                return _list;
            }
        }
        public T1()
        {

            InitializeComponent();
            this.Loaded += delegate
            {
                DependencyPropertyDescriptor prop = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty,typeof(TextBox));
                prop.AddValueChanged(text1, (s, e) =>
                {
                    SearchText = text1.Text;
                  });

                var pro2 = DependencyPropertyDescriptor.FromProperty(Selector.IsSelectionActiveProperty, typeof(Selector));
                pro2.AddValueChanged(grid1, (s, e) =>
                {

                    var b = (bool)grid1.GetValue(Selector.IsSelectionActiveProperty);
                    sel2.Text = b.ToString();
                    if (!b) {
                        sel2.Text = b.ToString();
                    }
                });

                pro2.AddValueChanged(tree1, (s, e) =>
                {

                    var b = (bool)tree1.GetValue(Selector.IsSelectionActiveProperty);
                    sel2.Text = b.ToString();
                    if (!b)
                    {
                        sel2.Text = b.ToString();
                    }
                });
            };
            this.Loaded += new RoutedEventHandler(T1_Loaded);
        }

        public ICollectionView CreateView(string con, object source) 
        {
            var cvs = new CollectionViewSource();
            cvs.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
            cvs.Source = source;
            cvs.View.Filter = (ee) =>
            {
                AcItem i = ee as AcItem;
                if (con.Contains(i.Name))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            };
            return cvs.View;
        }

        void T1_Loaded(object sender, RoutedEventArgs e)
        {
//             var bind = new Binding();
//             bind.Source = this;
//             bind.Path = new PropertyPath("Items");
//             bind.Converter = Items;
//             bind.ConverterParameter = this;
//             grid1.SetBinding(DataGrid.ItemsSourceProperty, bind);
            var conv = this.FindResource("goo") as TDataTemplateSelector;
            conv.control = this;
            grid1.ItemsSource = CreateView("RQ",Items);
            grid2.ItemsSource = CreateView("A", Items);
            //tree1.ItemsSource = CreateView("A",Items);
            var hia = this.FindResource("hia") as HierarchicalDataTemplate;

        }
        public void BClick(object sender, EventArgs e)
        {
//             _list.Apply(new AcItem() { Name = "R", Visible = true },
//                 new AcItem() { Name = "S", Visible = true },
//                 new AcItem() { Name = "A", Visible = true },
//                 new AcItem() { Name = "B", Visible = true },
//                 new AcItem() { Name = "C", Visible = true },
//                 new AcItem() { Name = "D", Visible = true },
//                 new AcItem() { Name = "E", Visible = true },
//                 new AcItem() { Name = "F", Visible = true }
//                 );
            "RSABDQEFDGDF".Select(o => new AcItem { Name = new String(o,1), Visible = null }).ToList().ForEach(o => Items.Add(o));
            //Items.NotifyCollectionChanged(NotifyCollectionChangedAction.Reset);

        }
        public void BClick2(object sender, EventArgs e)
        {
            var a = grid1.SelectedItems;
            grid1.SelectedItem = null;
            var t = GetTreeViewItem(tree1, text1.Text);
            if (t != null)
            {
                t.IsSelected = true;
                t.BringIntoView();
            }
        }
        /// <summary>
        /// Recursively search for an item in this subtree.
        /// </summary>
        /// <param name="container">
        /// The parent ItemsControl. This can be a TreeView or a TreeViewItem.
        /// </param>
        /// <param name="item">
        /// The item to search for.
        /// </param>
        /// <returns>
        /// The TreeViewItem that contains the specified item.
        /// </returns>
        private TreeViewItem GetTreeViewItem(ItemsControl container, string str)
        {
            if (container != null)
            {
                var item = container.DataContext as AcItem;
                if (item != null && item.Name.Equals(str))
                {
                    return container as TreeViewItem;
                }

                // Expand the current container
                if (container is TreeViewItem && !((TreeViewItem)container).IsExpanded)
                {
                    //container.SetValue(TreeViewItem.IsExpandedProperty, true);
                }

                // Try to generate the ItemsPresenter and the ItemsPanel.
                // by calling ApplyTemplate.  Note that in the
                // virtualizing case even if the item is marked
                // expanded we still need to do this step in order to
                // regenerate the visuals because they may have been virtualized away.

                container.ApplyTemplate();
                ItemsPresenter itemsPresenter =
                    (ItemsPresenter)container.Template.FindName("ItemsHost", container);
                if (itemsPresenter != null)
                {
                    itemsPresenter.ApplyTemplate();
                }
                else
                {
                    // The Tree template has not named the ItemsPresenter,
                    // so walk the descendents and find the child.
                    itemsPresenter = FindVisualChild<ItemsPresenter>(container);
                    if (itemsPresenter == null)
                    {
                        container.UpdateLayout();

                        itemsPresenter = FindVisualChild<ItemsPresenter>(container);
                    }
                }

                Panel itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0);


                // Ensure that the generator for this panel has been created.
                UIElementCollection children = itemsHostPanel.Children;


                for (int i = 0, count = container.Items.Count; i < count; i++)
                {
                    TreeViewItem subContainer;

                    {
                        subContainer =
                            (TreeViewItem)container.ItemContainerGenerator.
                            ContainerFromIndex(i);
                    }

                    if (subContainer != null)
                    {
                        // Search the next level for the object.
                        TreeViewItem resultContainer = GetTreeViewItem(subContainer, str);
                        if (resultContainer != null)
                        {
                            return resultContainer;
                        }
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// Search for an element of a certain type in the visual tree.
        /// </summary>
        /// <typeparam name="T">The type of element to find.</typeparam>
        /// <param name="visual">The parent element.</param>
        /// <returns></returns>
        private T FindVisualChild<T>(Visual visual) where T : Visual
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
            {
                Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
                if (child != null)
                {
                    T correctlyTyped = child as T;
                    if (correctlyTyped != null)
                    {
                        return correctlyTyped;
                    }

                    T descendent = FindVisualChild<T>(child);
                    if (descendent != null)
                    {
                        return descendent;
                    }
                }
            }

            return null;
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void tree1_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            //var s = sender as IInputElement;
            var s = e.OriginalSource as IInputElement;
            s.Focusable = true;
            Keyboard.Focus(s);
            //text1.Text = "";
        }

        private void text1_KeyDown(object sender, KeyEventArgs e)
        {
            SearchText = text1.Text;
        }

        private void grid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var s = grid1.SelectedItem as AcItem;
            if (s == null) sel.Text = "null";
            else
                sel.Text = s.Name;
        }

        private void grid1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show(sender.ToString());
        }

        private void Root_MouseLeave(object sender, MouseEventArgs e)
        {
            this.Focusable = true;
            Keyboard.Focus(this);
        }
    }
   // Note that this code looks for a Panel called, MyVirtualizingStackPanel.  This new type exposes a method that allows you to bring an item into view by passing in the item's index.
 
    public class MyVirtualizingStackPanel : VirtualizingStackPanel
    {
        /// <summary>
        /// Publically expose BringIndexIntoView.
        /// </summary>
        public void BringIntoView(int index)
        {
            
 
            this.BringIndexIntoView(index);
        }
    }
    public class AcItem : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        private string name; private bool? visible;
        public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } }
        public bool? Visible { get { return visible; } set { visible = value; NotifyPropertyChanged("Visible"); } }
    }

    public class ObservableList<T> : List<T>, INotifyCollectionChanged, IValueConverter, INotifyPropertyChanged where T : AcItem
    {
        public ObservableList () :base(1) {}
        private NotifyCollectionChangedEventHandler collectionChanged;
        public event NotifyCollectionChangedEventHandler CollectionChanged
        {
            add
            {
                collectionChanged += value;
            }
            remove
            {
                collectionChanged -= value;
            }
        }
        public void NotifyCollectionChanged(NotifyCollectionChangedAction action)
        {
            var temp = collectionChanged;
            if (temp != null)
            {
                temp(this, new NotifyCollectionChangedEventArgs(action));
            }
            var temp2 = PropertyChanged;
            if (temp2 != null)
            {
                temp2(this, new PropertyChangedEventArgs("Count"));
            }
        }
        public void Apply(IEnumerable<T> collection)
        {
            var diff = collection.Select(o => !this.Contains(o)).ToList();
            AddRange(collection);
            this.Sort((a, b) => a.Name.CompareTo(b.Name));
            NotifyCollectionChanged(NotifyCollectionChangedAction.Reset);
        }
        public void Apply(params T[] c)
        {
            Apply((IEnumerable<T>)c);
        }


        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
    public class TDataTemplateSelector : DataTemplateSelector,IValueConverter
    {
        public T1 control;
        public TDataTemplateSelector() { }
        public TDataTemplateSelector(T1 con) { control = con; }
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var i = item as AcItem;
            var c = container as FrameworkElement;
            if (i.Name.Equals("A"))
                return c.FindResource("dd") as DataTemplate;
            if (i.Name.Equals("F"))
                return c.FindResource("dd") as DataTemplate;
            else
                return c.FindResource("ss") as DataTemplate;
        }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (parameter != null && parameter is FrameworkElement)
            {
                var o = parameter as FrameworkElement;
                AcItem item1 = o.DataContext as AcItem;
                return item1.Visible;

            }
            if (parameter!= null &&parameter.Equals("Name"))
            {
                return "343".Length;
            }
            if (parameter != null && parameter.Equals("vis"))
            {
                return "343".Length;
            }
            if (parameter != null)
            {
                var tar = value as T1;
                return tar.CreateView("F", tar.Items);
            }
            AcItem item = value as AcItem;
            if (item != null)
            {
                if (item.Name.Equals("F"))
                {
                    return control.CreateView("A", control.Items);
                }
                if (item.Name.Equals("E"))
                {
                    return null;
                }
            }

            return control.CreateView("E", control.Items);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

}
